var mMaster;
var mDeck;
var mHand;
var mOponent;
var mTrump;
var mPlay;

var mHandSorted;

var cnt_errors = 0;
var error_prefix = ["Uh Oh! ", "That's cheating, ", "What's wrong man, ", "Holy Crap! "];
var error_wait = ["Haven't I told you to wait?!...", "Take it slow, your opponent's thinking...",
					"Just relax, calm down..."];

var card_ext = '.png';
var card_back = 'Blue_Back' + card_ext;

var interval_ready;
var interval_updateGame;
var interval_battleEnded;

var timeout_fadeprompt;

var is_attaker = false;

var is_throwSuspended = false;

var is_endRequested = false;

var tmp_endRequestCards;

var is_thrown = false;

var is_ended = false;

var mModal;

var ctr_streaks = 0;

var MAX_CARDSROW = 12;
var MAX_HANDCARDS = 6;
var MAX_PLAYCARDS = 6;
var SUITES = new Array('Clubs', 'Diamonds', 'Hearts', 'Spades');

var is_oponentCardsShown = 0;

$(function(){
	$.ajaxSetup({cache: false});
	interval_ready = setInterval(function(){
			is_oponentReady();	
		}, 1000);
	interval_battleEnded = setInterval(function(){
			is_battleEnded();	
		}, 5000);

	get_cards();

	initModal();
});

function is_battleEnded(){
	$.ajax({
		url: BASE_URL + 'game/is_battle_ended/' + (IS_MECHALLENGER == 1 ? MY_ID : OPONENT_ID),
		data: "",
		dataType: 'json',
		success: function(data){
			if(data == 1){
				mModal.open({
				content:
					'<h1>Game Over!</h1>' + 
					'<p><strong>' + OPONENT_NAME + '</strong> surrendered and forfeited the battle. This renders no points for you.</p>' + 
					'<button onclick="quit()">OK</button>',
				hideClose: true
				});
			}
		}
	});
}

function startInterval(key){
	if(key == 'updateGame'){
		// $.ajaxSetup({cache: false});
		clearInterval(interval_updateGame);
		interval_updateGame = setInterval(function(){
				updateGame();
			}, 1000);
	}
}

function is_oponentReady(){
	$.ajax({
		url: BASE_URL + 'game/is_oponent_ready/' + (IS_MECHALLENGER == 1 ? MY_ID : OPONENT_ID),
		data: "",
		dataType: 'json',
		success: function(data){
			if(data == 1){
				$('#play-prompt')[0].innerHTML = '<br/><button style="position:absolute; margin-left: -90px; margin-top: -5px" onclick="startGame()" class="font-large">Let\'s Get it On!</button>';
				clearInterval(interval_ready);
			}
		}
	});
}

/**
* Challenger gets the first 6 cards
*/
function startGame(){
	// $('#btn-sort')[0].hidden = null;
	$('#chkbox-sort')[0].checked = false;

	$('#play-prompt')[0].innerHTML = '';
	
	mHand = new Array();
	mHandSorted = new Array();
	mOponent = new Array();
	mPlay = new Array();

	for(var x = 1; x <= MAX_HANDCARDS * 2; x++){
		if((IS_MECHALLENGER == 1 && x <= MAX_HANDCARDS) || (IS_MECHALLENGER == 0 && x >= 7)){
			mHand.push(mDeck.pop());
		}
		else{
			mOponent.push(mDeck.pop());
		}

		$('.cards-deck')[0].remove();
	}
	mTrump = mDeck.pop();
	$('.cards-deck')[0].remove();

	setImage($('#card-trump')[0], DIR_CARDS + getCard(mTrump)['img'] + card_ext);

	arrangeHand();
	arrangOponent();
	/**
	* Set is_attaker to false para ma.true xa
	* If challenger do first attack.
	*/

	$('#player-prompt')[0].hidden = null;
	if(IS_MECHALLENGER == 1) is_attaker = false;
	else is_attaker = true;

	$('#ico-battle')[0].hidden = null;
	$('#text-battle')[0].hidden = null;

	shiftAttacker();
}

function runFunction(array, arrayView, func, params){
	if(func == 'push'){
		array.push(params[1]);
		if(params[2] != 'noview' && arrayView[array.length - 1] != null && params[1] != null){
			setImage(arrayView[array.length - 1], DIR_CARDS + getCard(params[1])['img'] + card_ext);
		}
	}
	else if(func == 'remove'){
		if(params == 'trump'){
			$('#card-trump')[0].remove();
		}
		else{
			array[params[1]] = null;
			arrayView[params[1]].hidden = "hidden";

			if(params[0] == "hand"){
				check_gameOver(mOponent, "oponent");
			}
		}
	}
	else if(func == 'pop'){
		array.pop();
		arrayView[0].remove();
	}
	else if(func == 'clear'){
		var lengthTmp = array.length;
		for(var x = 0; x < lengthTmp; x++){
			clearImage(arrayView[x]);
			array.pop();
		}
	}
	else if(func == 'shift'){
		shiftAttacker();
	}
	else if(func == 'rewrite'){
		compactArray(array);
		arrangOponent();
	}
	else if(func == 'end'){
		showButtonGroup(true, false, true);
		clearInterval(interval_updateGame);
		displayPromptText('<strong>' + OPONENT_NAME + '</strong> ended the streak. Decide which power thou shall weild.');
		is_ended = true;
	}
	else if(func == 'accept'){
		clearInterval(interval_updateGame);
		displayPromptText('<strong>' + OPONENT_NAME + '</strong> yield not the spirit to attack, and chose to accept.');
	}
	else if(func == 'requestend'){
		clearInterval(interval_updateGame);
		showButtonGroup(false, true, false);
		displayPromptText('<strong>' + OPONENT_NAME + '</strong> has accepted. End or upsurge the suffering.');
		is_endRequested = true;

		tmp_endRequestCards = {};
		tmp_endRequestCards[MY_ID] = [];
	}
	else if(func == 'endcollect'){
		$('#btn-collect')[0].hidden = null;
		displayPromptText('These cards are all yours. Collect.');
		clearInterval(interval_updateGame);
	}
	else if(func == 'collect'){
		displayPromptText('<strong>' + OPONENT_NAME + '</strong> was done collecting. Attack.');
		clearInterval(interval_updateGame);
		is_endRequested = false;
	}
}

function collect(){
	$('#btn-collect')[0].hidden = "hidden";
	// compactArray(mPlay);

	var obj = fillHandFromPlay();

	obj[MY_ID].push({"collect": -1});

	$.ajax({
		url: BASE_URL + 'game/update_battle/' + (IS_MECHALLENGER == 1 ? MY_ID : OPONENT_ID),
		type: 'POST',
		data: {'data': JSON.stringify(obj)},
		dataType: 'json',
		success: function(data){
				displayPromptText('You\'re left without choice to escape this burden. Defend.');
				startInterval('updateGame');

				console.log("Sent Update: %O", obj);
			}
		});
}

function updateGame(){
	$.ajax({
		url: BASE_URL + 'game/get_battle/' + (IS_MECHALLENGER == 1 ? MY_ID : OPONENT_ID),
		data: "",
		dataType: 'json',
		success: function(data){
			console.log("Pinged update: %O", data);

			var is_shifted = false;
			var is_oponentMoved = false;
			var oponentUpdates = data[OPONENT_ID.toString()];
			if(oponentUpdates != null){
				for(var idx in oponentUpdates){
					/**
					* Expected to be only one unique call to each function
					*/
					for(var func in oponentUpdates[idx]){
						if(func == 'shift' || func == 'accept') is_shifted = true;
						else if(func == 'endcollect') is_oponentMoved = false;

						if(oponentUpdates[idx][func][0] == 'hand'){
							runFunction(mOponent, $('.cards-oponent'), func, oponentUpdates[idx][func]);
						}
						else if(oponentUpdates[idx][func][0] == 'play'){
							if(func == 'push') is_oponentMoved = true;
							runFunction(mPlay, $('.cards-play'), func, oponentUpdates[idx][func]);
						}
						else if(oponentUpdates[idx][func][0] == 'deck'){
							runFunction(mDeck, $('.cards-deck'), func, oponentUpdates[idx][func]);
						}
						else{
							runFunction(null, null, func, oponentUpdates[idx][func]);
						}
					}
				}

				is_throwSuspended = false;

				if(is_oponentMoved) clearInterval(interval_updateGame);

				if(is_shifted){
					if(is_attaker){
						hideButtonGroup();

						$.ajax({
						url: BASE_URL + 'game/update_battle/' + (IS_MECHALLENGER == 1 ? MY_ID : OPONENT_ID),
						type: 'POST',
						data: {'data': JSON.stringify(fillHandFromDeck())},
						dataType: 'json',
						success: function(data){
							console.log("Sent Update: fillHandFromDeck");
							}
						});
					}
					else{

					}
				}
				else if(is_oponentMoved){
					if(is_attaker){
						displayPromptText('Attack!!');

						showButtonGroup(false, true, false);
					}
					else{
						displayPromptText('Defend thy Kingdom!');

						showButtonGroup(true, false, false);
					}
				}
			}
			else{
				console.log('data[' + OPONENT_ID.toString() + '] is null');
			}
		}
	});
}

function hideButtonGroup(){
	$("#btn-accept")[0].hidden = "hidden";
	$("#btn-end")[0].hidden = "hidden";
	$("#btn-attack")[0].hidden = "hidden";
}

function showButtonGroup(accept, end, attack){
	if(accept) $("#btn-accept")[0].hidden = null;
	else $("#btn-accept")[0].hidden = "hidden";

	if(end) $("#btn-end")[0].hidden = null;
	else $("#btn-end")[0].hidden = "hidden";

	if(attack) $("#btn-attack")[0].hidden = null;
	else $("#btn-attack")[0].hidden = "hidden";
}

function compactArray(array){
	for(var x = 0; x < array.length; x++){
		if(array[x] == null){
			array.splice(x--, 1);
		}
	}
	console.log("Array comapacted: %O", array);
}

function fillHandFromPlay(){
	var obj = {};
	obj[MY_ID] = [];
	compactArray(mHand);
	for(var x = mPlay.length - 1; x >= 0; x--){
		/*
		* Solution for problem #2
		* In case there are nulls in between disregard, this calls not for compactArray(mPlay)
		*/
		if(mPlay[mPlay.length - 1] == null){
			mPlay.pop();
		}
		else{
			clearImage($('.cards-play')[x]);
			mHand.push(mPlay.pop());
			obj[MY_ID].push({"push": ["hand", mHand[mHand.length - 1], "noview"]});
		}
	}
	arrangeHand();
	obj[MY_ID].push({"rewrite": ["hand"]});

	obj[MY_ID].push({"clear": ["play"]});

	return obj;
}

function fillHandFromDeck(){
	var obj = {};
	obj[MY_ID] = [];
	compactArray(mHand);

	for(var x = mHand.length; x < MAX_HANDCARDS; x++){
		if($('#card-trump').length <= 0) break;

		if(mDeck.length > 0){
			mHand.push(mDeck.pop());
			$('.cards-deck')[0].remove();
			obj[MY_ID].push({"push": ["hand", mHand[mHand.length - 1], "noview"]});
			obj[MY_ID].push({"pop": ["deck"]});
		}
		else{
			mHand.push(mTrump);
			$('#card-trump')[0].remove();
			obj[MY_ID].push({"push": ["hand", mTrump, "noview"]});
			obj[MY_ID].push({"remove": "trump"});
		}
	}
	arrangeHand();

	obj[MY_ID].push({"rewrite": ["hand"]});

	return obj;
}

function endAttack(){
	is_oponentCardsShown--;

	var obj = fillHandFromDeck();

	// var lengthTmp = mPlay.length;
	// for(var x = 0; x < lengthTmp; x++){
	// 	$('.cards-play')[x].removeAttribute('src');
	// 	mPlay.pop();
	// }
	
	hideButtonGroup();
	// obj[MY_ID].push({"clear": ["play"]});
	// obj[MY_ID].push({"shift": -1});

	var prompt = '';
	/**
	* Ning.accept ug una
	*/
	if(is_endRequested){
		while(tmp_endRequestCards[MY_ID].length > 0){
			obj[MY_ID].splice(0, 0, tmp_endRequestCards[MY_ID].pop());
		}
		obj[MY_ID].push({"endcollect": -1});
		is_endRequested = false;
		prompt = 'Let us await the gathering of such blessings...';

		check_gameOver(mHand, "hand");
	}
	else{
		obj[MY_ID].push({"end": -1});
		prompt = 'The time is now to wait for <strong>' + OPONENT_NAME + '</strong>\'s decision...';
	}

	$.ajax({
		url: BASE_URL + 'game/update_battle/' + (IS_MECHALLENGER == 1 ? MY_ID : OPONENT_ID),
		type: 'POST',
		data: {'data': JSON.stringify(obj)},
		dataType: 'json',
		success: function(data){
				// shiftAttacker();
				console.log('endAttack');
				startInterval('updateGame');
				displayPromptText(prompt);
				is_throwSuspended = true;
				console.log("Sent Update: %O", obj);
			}
		});
}

function attack(){
	ctr_streaks = 0;
	is_oponentCardsShown--;

	var obj = fillHandFromDeck();

	hideButtonGroup();

	var lengthTmp = mPlay.length;
	for(var x = 0; x < lengthTmp; x++){
		clearImage($('.cards-play')[x]);
		mPlay.pop();
	}
	obj[MY_ID].push({"clear": ["play"]});
	obj[MY_ID].push({"shift": -1});


	$.ajax({
		url: BASE_URL + 'game/update_battle/' + (IS_MECHALLENGER == 1 ? MY_ID : OPONENT_ID),
		type: 'POST',
		data: {'data': JSON.stringify(obj)},
		dataType: 'json',
		success: function(data){
				shiftAttacker();
				console.log("Sent Update: %O", obj);
			}
		});
}

function acceptCards(){
	ctr_streaks = 0;
	is_oponentCardsShown--;

	var obj = {};
	obj[MY_ID] = [];

	hideButtonGroup();

	is_throwSuspended = true;

	var prompt = '';

	/**
	* Hulat pa ka magdungag imo kalaban
	*/
	if(!is_ended){
		prompt = 'Ye shall seek to wait for <strong>' + OPONENT_NAME + '</strong> to end...';
		obj[MY_ID].push({"requestend": -1});
	}
	else{
		is_ended = false;

		obj = fillHandFromPlay();

		prompt = 'You desire such cards. So shall it be.';
		obj[MY_ID].push({"accept": -1});
	}

	$.ajax({
		url: BASE_URL + 'game/update_battle/' + (IS_MECHALLENGER == 1 ? MY_ID : OPONENT_ID),
		type: 'POST',
		data: {'data': JSON.stringify(obj)},
		dataType: 'json',
		success: function(data){
				displayPromptText(prompt);

				console.log('acceptCArds');
				startInterval('updateGame');

				console.log("Sent Update: %O", obj);
			}
		});
}

function setImage(view, img){
	view.src = img;
	console.log(view.class);
	view.className += ' shadow-card';
}

function clearImage(view){
	view.removeAttribute('src');
	var idx;
	if((idx = view.className.indexOf(' shadow-card')) != -1) view.className = view.className.substring(0, idx);
}

function shiftAttacker(){
	/**
	* If me is the attacker
	*/
	if((is_attaker = !is_attaker)){
		$('#ico-battle')[0].src =  DIR_IMAGES + '/ico-attack.jpg';
		$('#text-battle')[0].innerHTML = 'Attacker';

		if($('#player-prompt-text')[0].innerHTML == '<span></span>') displayPromptText('As a Challenger, the Gods granted you to throw first... ');
		else displayPromptText('Now victory shall be yours. Attack!...');
	}
	else{
		$('#ico-battle')[0].src = DIR_IMAGES + '/ico-defend.jpg';
		$('#text-battle')[0].innerHTML = 'Defender';
		
		if($('#player-prompt-text')[0].innerHTML == '<span></span>') displayPromptText('Wait for the Challenger\'s throw...');
		else displayPromptText('Now the odds are against you. Defend!...');
		
		console.log('shiftAttacker');
		startInterval('updateGame');
	}

	get_playCards();
}

function displayPromptText(text){
	$('#player-prompt-text').fadeIn(250);
	$('#player-prompt-text')[0].innerHTML = text;
}

function displayError(postfix_error){
	displayPromptText(error_prefix[cnt_errors++ % error_prefix.length] + postfix_error);
	clearTimeout(timeout_fadeprompt);
	timeout_fadeprompt = setTimeout(function(){$('#player-prompt-text').fadeOut();}, 3000);
}

function surrender(){
	mModal.open({
		content:
			'<h1>Surrender?!</h1>' + 
			'<p>Your such a loser dude! Forfeiting this battle will <strong>deduct your wins by 1 pt.</strong>.<br/>Ye sure to quittin\' man?</p>' + 
			'<button onclick="reallySure()">Yes</button>&nbsp&nbsp<button onclick="closeModal()">No</button>',
		hideClose: true
		});
}

function closeModal(){
	mModal.close();
}

function quit(){
	$.ajax({
		url: BASE_URL + 'game/surrender/' + (IS_MECHALLENGER == 1 ? MY_ID : OPONENT_ID),
		dataType: 'json',
		success: function(data){
				window.location.href = BASE_URL + 'admin/surrender/';
			}
		});
}

function decreaseWins(){
	var content = '';
	console.log(WINS + ' ' + WINS_PER_RANK + ' ' + ((WINS - 1) % WINS_PER_RANK));
	if(WINS - 1 == WINS_PER_RANK - 1){
		var rankData = CLASSES[0]['ranks'][0];
		content = '<h1>Holy Crap!</h1>' +
				'<p>The gods disregarded your Class and brought you back to a mundane.</p><br/>' + 
				'<img style="margin-bottom: -5px;" src="' + DIR_IMAGES + rankData['img'] + card_ext + '"/><br/>' + 
				'<strong class="subscript">You are now a <span class="outline" style="color: blue; font-size: 14px;">' + 
					rankData['name'] + 
				'</span></strong></br>' + 
				'<br/><button onclick="quit()">OK</button>';
		updateRank(openModal(content), -1, 0);
	}
	else if((WINS - 1) % WINS_PER_RANK == WINS_PER_RANK - 1){
		var rankData = CLASSES[MY_CLASS]['ranks'][Math.floor((WINS - 1) / WINS_PER_RANK - 1)];
		content = '<h1>Your Rank has diminished!</h1>' +
					'<img style="margin-bottom: -5px;" src="' + DIR_IMAGES + rankData['img'] + card_ext + '"/><br/>' + 
					'<strong class="subscript">You are now a <span class="outline" style="color: blue; font-size: 14px;">' + 
						rankData['name'] + 
					'</span></strong></br>' + 
					'<br/><button onclick="quit()">OK</button>';
		updateRank(openModal(content), -1, null);
	}
	else{
		updateRank(function(data){
			quit();
		}, -1, null);
	}
}

function reallySure(){
	mModal.open({
		content:
			'<h1>Please Don\'t Surrender...</h1>' + 
			'<p>Really? You sure?</p>' + 
			'<button onclick="decreaseWins()">Yes</button>&nbsp&nbsp<button onclick="closeModal()">No</button>',
		hideClose: true
		});
}

function classHover(idx, show){
	if(show){
		$('#class-desc' + idx).fadeIn();
	}
	else{
		$('#class-desc' + idx).fadeOut();
	}
}

function skillHover(idx, show){
	if(show){
		$('#skill-desc' + idx).fadeIn();
	}
	else{
		$('#skill-desc' + idx)[0].style.display = 'none';
	}
}

function updateRank(callback, hasWon, classId=null){
	$.ajax({
		url: BASE_URL + 'game/update_rank/' + MY_ID + '/' + hasWon + '/' + (classId == null ? '' : classId),
		dataType: 'json',
		success: callback
		});
}

function openModal(content, modalParam=null){
	if(modalParam == null){
		mModal.open({
		content: content,
		hideClose: true
		});
	}
	else {
		var rankData = CLASSES[modalParam]['ranks'][(WINS + 1) / WINS_PER_RANK - 1];

		mModal.open({
		content: '<h1>You recieved a new Rank!</h1>' +
				'<img style="margin-bottom: -5px;" src="' + DIR_IMAGES + rankData['img'] + card_ext + '"/><br/>' + 
				'<strong class="subscript">You are now a <span class="outline" style="color: blue; font-size: 14px;">' + 
					rankData['name'] + 
				'</span></strong></br>' + 
				'<br/><button onclick="quit()">OK</button>',
		hideClose: true
		});
	}
}

function check_gameOver(array, arrayName){
	if(mDeck.length == 0 && $('#card-trump').length <= 0){
		for(var idx in array){
			if(array[idx] != null){
				return false;
			}
		}
		/**
		* End the game
		*/
		if(arrayName == "hand"){
			var content = '<h1>Game Over!</h1>' + 
							'<p>You Win! <strong>' + OPONENT_NAME  + '</strong> will bear this shame forever.</p>';
			if(WINS + 1 == WINS_PER_RANK){
				content += '<h1>Congratulations!</h1>' +
						'<p>The gods have give you the chance to be born again.</p>' + 
						'<strong class="subscript">Choose a new Class:</strong></br><br/>';

				for(var x = 1; x < CLASSES.length; x++){
					content += '<button id="class-btn' + x + '" onclick="updateRank(openModal(null, ' + x + '), 1, ' + x + ')" onmouseover="classHover(' + x +
								', true)" onmouseout="classHover(' + x + ', false)" class="class-btn">' + 
								'<img src="' + DIR_IMAGES + CLASSES[x]['img'] + card_ext + '"/><br/>' + 
								'<strong class="outline" style="font-size: 12px; color: blue">' + CLASSES[x]['name'] + '</strong>' + 
								'<br/>' +
								'<span id="class-desc' + x + '" style="font-size: 10px; text-transform: none; display: none">' +
									CLASSES[x]['desc'] +
								'</span>' + 
							'</button>&nbsp&nbsp';
				}
				openModal(content);
				
			}
			else if((WINS + 1) % WINS_PER_RANK == 0){
				var rankData = CLASSES[MY_CLASS]['ranks'][(WINS + 1) / WINS_PER_RANK - 1];
				content += '<h1>You recieved a new Rank!</h1>' +
							'<img style="margin-bottom: -5px;" src="' + DIR_IMAGES + rankData['img'] + card_ext + '"/><br/>' + 
							'<strong class="subscript">You are now a <span class="outline" style="color: blue; font-size: 14px;">' + 
								rankData['name'] + 
							'</span></strong></br>' + 
							'<br/><button onclick="quit()">OK</button>';
				updateRank(openModal(content), 1, null);
			}
			else{
				content += '<br/><button onclick="quit()">OK</button>';
				updateRank(openModal(content), 1, null);
			}

			
		}
		else{
			updateRank(function(data){
				mModal.open({
				content:
				'<h1>Game Over!</h1>' + 
				'<p>You Lose! <strong>' + OPONENT_NAME  + '</strong> proved stronger against you.</p>' + 
				'<button onclick="quit()">OK</button>',
				hideClose: true
				});
			}, 0, null);
			
		}
		clearInterval(interval_updateGame);
	}
}

function throwCard(idx){
	/**
	* Maximum cards to be defended must be as many as have been originally dealt to each player (6 or 7) or until the defender runs out of cards, whichever is less.
	*/
	if(Math.floor(mPlay.length / 2) >= MAX_HANDCARDS){
		return false;
	}
	/*
	* To solve conditions:
	* => If defender accepts card can still add until of the same value and <= number of cards defender
	* => Cont...Cant attack anymore if thrown is equal to defenders cards
	*/
	if(is_endRequested){
		var thrownCard = getCard(mHand[idx]);
		if(isFaceInPlay(thrownCard['img'])){
			/**
			* Solution to problem #2
			* +1 for the card not rebutt, and oponent accepted
			*/
			if(tmp_endRequestCards[MY_ID].length / 2 + 1 < mOponent.length){
				mPlay.push(null);
				mPlay.push(mHand[idx]);
				setImage($('.cards-play')[mPlay.length - 1], DIR_CARDS + getCard(mHand[idx])['img'] + card_ext);
				tmp_endRequestCards[MY_ID].push({"push": ["play", null]});
				tmp_endRequestCards[MY_ID].push({"push": ["play", mHand[idx]]});
				
				mHand[x] = null;
				$('.cards-hand')[mHandSorted[idx]].hidden = "hidden";
				tmp_endRequestCards[MY_ID].push({"remove": ["hand", idx]});
			}
			else{
				displayError('thou shall abuse one\'s power. You can\'t throw that much.');
			}
		}
		else{
			displayError('a card of <strong>' + thrownCard['face'] + '</strong> is non-existing in play.');
		}

		return false;
	}
	/**
	* Solution to problem #2
	* Can't throw if oponent has not much cards
	* Applies only to attacker
	*/
	else if(mOponent.length == 0 && is_attaker){
		displayError('Thou shall abuse one\'s power. <strong>' + OPONENT_NAME + '</strong> has not much to defend.');
		return false;
	}

	/**
	* To solve cases where a there are two throws in one streak due to slow internet
	*/
	if(is_thrown) return false;
	
	var obj = {};
	obj[MY_ID] = [
				{"push": ["play", mHand[idx]]},
				{"remove": ["hand", idx]}
				];
	var gameUpdates = JSON.stringify(obj);
	/**
	* Attacker conditions
	*/
	if(is_attaker && mPlay.length % 2 == 0 && !is_throwSuspended){
		var thrownCard = getCard(mHand[idx]);
		if(isFaceInPlay(thrownCard['img'])){
			//ok
			console.log('OK: Face is in play.');
		}
		else if(mPlay.length == 0){

		}
		else{
			displayError('there are no <strong>' + thrownCard['face'] + '</strong> in the play.');
			gameUpdates = '';
		}
	}
	/**
	* Defender conditions
	*/
	else if(!is_attaker && mPlay.length % 2 == 1 && !is_throwSuspended){
		var mod = mMaster['Clubs'].length;
		var strTmp = '';

		strTmp = getCard(mHand[idx])['img'];
		var thrownCardFace = strTmp[strTmp.length - 1];
		strTmp = getCard(mPlay[mPlay.length - 1])['img'];
		var attackCardFace = strTmp[strTmp.length - 1];
		strTmp = getCard(mTrump)['img'];
		var trumpCardFace = strTmp[strTmp.length - 1];
		/**
		* The attack was a trump
		*/
		if(attackCardFace == trumpCardFace){
			if(thrownCardFace == trumpCardFace && mHand[idx] % mod > mPlay[mPlay.length - 1] % mod){
				//ok
				console.log('OK: Attack is Trump. And throw is a greater trump');
			}
			else{
				displayError("this card is not a Trump with a higher face value.");
				gameUpdates = '';
			}
		}
		/**
		* The attack was a non-trump
		*/
		else{
			if(thrownCardFace == trumpCardFace || (attackCardFace == thrownCardFace && mHand[idx] % mod > mPlay[mPlay.length - 1] % mod)){
				//ok
				console.log('OK: Attack is Non-Trump. And throw is greater same suite');
			}
			else{
				displayError("defend with a higher face value of the same suit or a Trump.");
				gameUpdates = '';
			}
		}
	}
	else if(!is_throwSuspended){
		displayPromptText(error_wait[cnt_errors++ % error_wait.length]);
		gameUpdates = '';
	}
	else{
		displayError("wait for <strong>" + OPONENT_NAME + "</strong>'s decision...");
		gameUpdates = '';
	}

	/**
	* Write to file and start interval
	*/
	if(gameUpdates != ''){
		if(!is_attaker){
			++ctr_streaks;
			checkStreaks();
		}

		is_thrown = true;

		$.ajax({
		url: BASE_URL + 'game/update_battle/' + (IS_MECHALLENGER == 1 ? MY_ID : OPONENT_ID),
		type: 'POST',
		data: {'data': gameUpdates},
		dataType: 'json',
		success: function(data){
				/**
				* Gikan ni sa gawas gi.balhin naq
				*/
				cnt_errors = 0;
			
				mPlay.push(mHand[idx]);
				setImage($('.cards-play')[mPlay.length - 1], DIR_CARDS + getCard(mHand[idx])['img'] + card_ext);
				
				mHand[idx] = null;
				check_gameOver(mHand, "hand");
				$('.cards-hand')[mHandSorted[idx]].hidden = "hidden";

				console.log('throwcard');
				startInterval('updateGame');
				if(is_attaker) displayPromptText('Wait for <strong>' + OPONENT_NAME + '</strong>\'s rebutt...');
				else displayPromptText('Wait for the next strike...');

				hideButtonGroup();

				is_thrown = false;

				console.log("Sent Update: %O", obj);

				/**
				* This part is added for skills
				*/

			}
		});
	}
}

function activateSkill(idx){
	if(idx == 0){
		$('#skill-btn' + idx).fadeOut();
		is_oponentCardsShown = 2;
		arrangOponent();
	}
}

function sortAndArrange(){
	$('#chkbox-sort')[0].checked = !$('#chkbox-sort')[0].checked;
	arrangeHand();
}

function sort(){
	mHandSorted.length = mHand.length;
	if($('#chkbox-sort')[0].checked){
		
		mHandSorted = [];
		strTmp = getCard(mTrump)['img'];
		var trumpCardSuite = strTmp[strTmp.length - 1];

		var is_existing = {};
		for(var idx in mMaster){
			is_existing[idx[0]] = false;
		}

		for(var idx in mHand){

			var cardA = getCard(mHand[idx])['img'];
			var cardSuiteA = cardA[cardA.length - 1];
			var cardValueA = mHand[idx] % mMaster[SUITES[0]].length;
			var x;
			if(is_existing[cardSuiteA]){
				var found = false;
				for(x in mHandSorted){
					var cardB = getCard(mHand[mHandSorted[x]])['img'];
					var cardSuiteB = cardB[cardB.length - 1];
					var cardValueB = mHand[mHandSorted[x]] % mMaster[SUITES[0]].length;

					if(cardSuiteA == cardSuiteB) found = true;

					if(found && (cardSuiteA != cardSuiteB || (cardSuiteA == cardSuiteB && cardValueA >= cardValueB))){
						x;
						break;
					}
				}
			}
			else{
				if(cardSuiteA == trumpCardSuite){
					x = 0;
				}
				else{
					x = mHandSorted.length;
				}
				is_existing[cardSuiteA] = true;
			}
			mHandSorted.splice(x, 0, idx);
		}
	}
	else{
		for(var idx in mHand){
			mHandSorted[idx] = idx;
		}
	}
}

function checkStreaks(){
	if(ctr_streaks < 2) return false;

	var idx;
	if(ctr_streaks > MAX_PLAYCARDS - 1) idx = SKILLS.length - 1;
	else idx = ctr_streaks - 2;

	if($('#skill-btn' + idx)[0].style.display == 'none'){
		$('#skill-btn' + idx).fadeIn();
		mModal.open({
		content:
			'<h1>You recieved a new Skill!</h1>' +
			'<img style="margin-bottom: -5px;" src="' + DIR_IMAGES + SKILLS[idx]['img'] + card_ext + '"/><br/>' + 
			'<strong class="subscript" style="font-size: 12px">' + 
				'<span class="outline" style="color: blue; font-size: 14px;">' + SKILLS[idx]['name'] + '</span><br/>' +
				SKILLS[idx]['desc'] + 
			'</strong>'
		});
	}
}

function isFaceInPlay(cardImg){
	for(var idx in mPlay){
		playCardImg = getCard(mPlay[idx])['img'];
		if(playCardImg.substring(0, playCardImg.length - 1) == cardImg.substring(0, cardImg.length - 1)){
			return true;
		}
	}
	return false;
}

function arrangOponent(){
	// var cardsOponent = $('.cards-oponent');
	// for(var x = 0; x < cardsOponent.length; x++){
	// 	if(mOponent[x] != null){
	// 		cardsOponent[x].hidden = null;
	// 		cardsOponent[x].src = DIR_CARDS + card_back;
	// 	}
	// 	else{
	// 		cardsOponent[x].hidden = "hidden";
	// 	}
	// }
	var parentHeight = 200;

	var tmpLength = mOponent.length;
	var currLength = 0;
	if(tmpLength > MAX_CARDSROW) tmpLength -= (currLength = MAX_CARDSROW);
	else currLength = tmpLength;

	var oponentHand = '';
	var tilt = 15;
	var factor = (-tilt - tilt) / currLength;
	var marginLeft = 0;

	tilt += factor;
	var marginTop = tilt;
	for(var x = 0; x < mOponent.length; x++){
		if(x % MAX_CARDSROW == 0 && x != 0){
			tilt = 15;
			if(tmpLength > MAX_CARDSROW) tmpLength -= (currLength = MAX_CARDSROW);
			else currLength = tmpLength;
			factor = (-tilt - tilt) / currLength;

			marginLeft = ((MAX_CARDSROW * 50) - (currLength * 50)) / 2;
			tilt += factor;

			marginTop += 90;

			parentHeight += 50;
		}

		if(mOponent[x] != null){
			oponentHand += '<img class="cards-oponent" style="margin: ' + marginTop + 'px 0px 0px ' + marginLeft + 'px;' + 
					'-webkit-transform: rotate(' + tilt + 'deg); -moz-transform: rotate(' + tilt + 'deg); -o-transform: rotate(' + tilt + 'deg); ' + 
					'-ms-transform: rotate(' + tilt + 'deg); transform: rotate(' + tilt + 'deg); ' + 
					'z-index: ' + -x + '" src="' + DIR_CARDS + (is_oponentCardsShown > 0 ? getCard(mOponent[x])['img'] + card_ext : card_back) + '">'; 
		}
		
		marginTop += tilt;
		marginLeft += 50;
		tilt += factor;
	}
	$('#oponent-hand')[0].innerHTML = oponentHand;
	$('#oponent-hand')[0].style.height = parentHeight + 'px';
}

function arrangeHand(){
	sort();
	// var cardsHand = $('.cards-hand');
	// for(var x = 0; x < cardsHand.length; x++){
	// 	if(mHand[x] != null){
	// 		cardsHand[x].hidden = null;
	// 		cardsHand[x].src = DIR_CARDS + getCard(mHand[x])['img'] + card_ext;
	// 	}
	// 	else{
	// 		cardsHand[x].hidden = "hidden";
	// 	}
	// }
	var cardRaise = 0;
	var parentHeight = 200;

	var tmpLength = mHand.length;
	var currLength = 0;
	if(tmpLength > MAX_CARDSROW) tmpLength -= (currLength = MAX_CARDSROW);
	else currLength = tmpLength;

	var cardsHand = '';
	var tilt = -15;
	var factor = (-tilt - tilt) / currLength;

	var marginLeft = 0;

	tilt += factor;
	var marginTop = -tilt + -tilt * 2;
	var marginBottom = 0;
	for(var x = 0; x < mHand.length; x++){
		if(x % MAX_CARDSROW == 0 && x != 0){
			tilt = -15;
			if(tmpLength > MAX_CARDSROW) tmpLength -= (currLength = MAX_CARDSROW);
			else currLength = tmpLength;
			factor = (-tilt - tilt) / currLength;

			marginLeft = ((MAX_CARDSROW * 50) - (currLength * 50)) / 2;
			tilt += factor;

			marginTop += 30;

			parentHeight += 50;

			cardRaise++;
		}

		if(mHand[mHandSorted[x]] != null){
			cardsHand += '<img class="cards-hand card-raise' + cardRaise + '" style="margin: ' + marginTop + 'px 0px 0px ' + marginLeft + 'px;' + 
						'-webkit-transform: rotate(' + tilt + 'deg); -moz-transform: rotate(' + tilt + 'deg); -o-transform: rotate(' + tilt + 'deg); ' + 
						'-ms-transform: rotate(' + tilt + 'deg); transform: rotate(' + tilt + 'deg);' + 
						'" onclick="throwCard(' + mHandSorted[x] + ')" src="' + DIR_CARDS + getCard(mHand[mHandSorted[x]])['img'] + card_ext + '">';
		}
		
		marginTop += tilt;
		marginLeft += 50;
		tilt += factor;
	}
	$('#my-hand')[0].innerHTML = cardsHand;
	$('#my-hand')[0].style.height = parentHeight + 'px';
}

function get_cards(){
	$.ajax({
		url: BASE_URL + 'game/get_cards/' + (IS_MECHALLENGER == 1 ? MY_ID : OPONENT_ID),
		data: "",
		dataType: 'json',
		success: function(data){
			mMaster = data['master'];
			mDeck = data['deck'];
			arrangeDeck();
		}
	});
}

function get_playCards(){
	var cardsPlay = '';
	for(var x = 0; x < MAX_PLAYCARDS; x++){
		cardsPlay += '<div style="display:inline-block; margin: 0px 0px 0px 0px; width: 160px">';

		cardsPlay += '<img class="cards-play" style="margin: ' + (is_attaker ? '40' : '0') + 'px 0px 0px 0px">';
		cardsPlay += '<img class="cards-play" style="margin: ' + (is_attaker ? '0' : '40') + 'px 0px 0px 40px">';
		cardsPlay += '</div>';
	}
	$('#play')[0].innerHTML = cardsPlay;
}

function getCard(idx){
	var suiteIdx = SUITES[Math.floor(idx / mMaster[SUITES[0]].length)];
	var faceIdx = idx % mMaster[SUITES[0]].length;

	return mMaster[suiteIdx][faceIdx];
}

function arrangeDeck(){

	var cardsDeck = '';
	var margin = 0;

	for(var idx in mDeck){
		cardsDeck += '<img class="cards-deck" src="' + DIR_CARDS + card_back +
					'" style="margin: ' + margin + 'px 0px 0px ' + margin + 'px; z-index: ' + -margin + '; ' + 
					(idx == mDeck.length - 1 ? 'box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.5);' : '') + 
					'"/>';
		margin +=1; 
	}

	$('#deck')[0].innerHTML = cardsDeck;
}

function initModal(){
	mModal = (function(){
	    var 
	    method = {},
	    $overlay,
	    $modal,
	    $content,
	    $close;

	    // Append the HTML
	    $overlay = $('<div id="modal-overlay"></div>');
		$modal = $('<div id="modal"></div>');
		$content = $('<div id="modal-content"></div>');
		$close = $('<a id="modal-close" href="#">close</a>');

		$modal.hide();
		$overlay.hide();
		$modal.append($content, $close);

		$(document).ready(function(){
		    $('body').append($overlay, $modal);
		});

	    // Center the modal in the viewport
	    method.center = function () {
		    var top, left;

		    top = Math.max($(window).height() - $modal.outerHeight(), 0) / 2;
		    left = Math.max($(window).width() - $modal.outerWidth(), 0) / 2;

		    $modal.css({
		        top:top + $(window).scrollTop(), 
		        left:left + $(window).scrollLeft()
		    });
		};

	    // Open the modal
	    method.open = function (settings) {
		    $content.empty().append(settings.content);
		    
		    if(settings.hideClose){
		    	$close.hide();
		    }
		    else{
		    	$close.show();
		    }

		    $modal.css({
		        width: settings.width || 'auto', 
		        height: settings.height || 'auto'
		    })

		    method.center();

		    $(window).bind('resize.modal', method.center);

		    $modal.show();
		    $overlay.show();
		};

	    // Close the modal
	    method.close = function () {
		    $modal.hide();
		    $overlay.hide();
		    $content.empty();
		    $(window).unbind('resize.modal');
		};

		$close.click(function(e){
		    e.preventDefault();
		    method.close();
		});

		// $overlay.click(function(e){
		// 	e.preventDefault();
		//     method.close();
		// });

	    return method;
	}());
}